﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;

namespace Esb.Soa.Domain.Monitor
{
    /// <summary>
    /// 调度者基类
    /// </summary>
    public abstract class DispatcherBase : IDispatcher, IDisposable
    {

        #region IDispatcher Members

        /// <summary>
        /// 开始
        /// </summary>
        /// <param name="isStartImmediate"></param>
        public void Start()
        {
            timer = new Timer(Interval);
            if (IsStartImmediate)
            {
                Task.Factory.StartNew(Dispatch).ContinueWith(t =>
                {
                    timer.Elapsed += On_Dispatching;
                    timer.Start();
                });
            }
            else
            {
                timer.Elapsed += On_Dispatching;
                timer.Start();
            }
        }

        /// <summary>
        /// 停止
        /// </summary>
        public void Stop()
        {
            Dispose(true);
        }

        /// <summary>
        /// 暂停
        /// </summary>
        public void Pause()
        {
            timer.Elapsed -= On_Dispatching;
            timer.Stop();
        }

        /// <summary>
        /// 继续
        /// </summary>
        public void Continue()
        {
            timer.Elapsed += On_Dispatching;
            timer.Start();
        }

        #endregion

        #region IDisposable Members

        /// <summary>
        /// 回收
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
        }

        /// <summary>
        /// 回收标记
        /// </summary>
        bool isDisposed;

        /// <summary>
        /// 回收
        /// </summary>
        /// <param name="disposing"></param>
        void Dispose(bool disposing)
        {
            if (!isDisposed)
            {
                if (disposing)
                {
                    if (timer != null)
                    {
                        timer.Stop();
                        timer.Elapsed -= On_Dispatching;
                    }
                }
                isDisposed = true;
                if (disposing)
                {
                    GC.SuppressFinalize(this);
                }
            }
        }

        /// <summary>
        /// 析构函数
        /// </summary>
        ~DispatcherBase()
        {
            Dispose(false);
        }

        #endregion

        #region Events

        /// <summary>
        /// 调度事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void On_Dispatching(object sender, ElapsedEventArgs e)
        {
            timer.Elapsed -= On_Dispatching;
            timer.Stop();
            Dispatch();
            timer.Elapsed += On_Dispatching;
            timer.Start();
        }

        #endregion

        #region Fields

        /// <summary>
        /// 调度计时器
        /// </summary>
        Timer timer;

        #endregion

        #region Override

        /// <summary>
        /// 调度间隔时间
        /// </summary>
        protected abstract long Interval { get; }

        /// <summary>
        /// 是否立即启动调度
        /// </summary>
        protected abstract bool IsStartImmediate { get; }

        /// <summary>
        /// 调度
        /// </summary>
        protected abstract void Dispatch();

        #endregion

    }
}
